//
//  testsBlock.swift
//  JuSwift
//
//  Created by Juvid on 2016/12/19.
//  Copyright © 2016年 Juvid. All rights reserved.
//

import UIKit
//无参无返回值
typealias funcBlock = () -> () //或者 () -> Void
//返回值是String
typealias funcBlockA = (Int,Int) -> String
//返回值是一个(block)函数指针，入参为String
typealias funcBlockB = (Int,Int) -> (String)->()
//返回值是一个(block)函数指针，入参为String 返回值也是String
typealias funcBlockC = (Int,Int) -> (String,String)->String

class JuBlock: NSObject {

    var names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
    var namess = ["zhu", "tian", "wei", "jute", "juvid"]

    //block作为属性变量
    var blockProperty : (Int,Int) -> String = {a,b in return ""
        /**/
    } // 带初始化方式
    var blockPropertyNoReturn : (String) -> () = { param  in

    }

    var blockPropertyA : funcBlockA?  //这写法就可以初始时为nil了,因为生命周其中，(理想状态)可能为nil所以用?
    var blockPropertyB : funcBlockB!  //这写法也可以初始时为nil了,因为生命周其中，(理想状态)认为不可能为nil,所以用!

    let juCompletionBlock1: (String,String) -> String = {string2,string1 in
        NSLog(string2)
        return "第一层"
    }
//    let juCompletionBlock2: (String) -> () = { [weak self] string2  in
//        NSLog(string2)
//
//    }

    func testFunc() {
        let juCompletionBlock: (String, String) -> String = {string1, string2 in

            return "闭包"
        }
        let blockBack  = juCompletionBlock("参数1","参数2");
        NSLog(blockBack)

        names = names.sorted(by: backward)
        namess = names.sorted(by: { (s1: String, s2: String) -> Bool in

            return s1 > s2
        })

        NSLog("数组1%@", names)
        NSLog("数组2%@", namess)
        juBlockClosure2(1)("32342","r4544")

//        闭包函数调用太随意了
        // 以下是不使用尾随闭包进行函数调用
        juBlockClosure(closure: {string1,string2 in
            NSLog("闭包主体部分1:参数1：%@，参数2：%@",string1,string2)
            return "123"
            // 闭包主体部分
        })
        // 以下是使用尾随闭包进行函数调用
        juBlockClosure() { string,string2 in
            NSLog("闭包主体部分2")
            return "321"
            // 闭包主体部分 
        }
        juBlockClosure { (string1, string2) -> String in
             NSLog("闭包主体部分3")
            return "456"
        }

        testBlockA { (num1, num2) -> String in
            return "3"
        };

//       testBlockB { (num1, num2) -> (String) -> () in
//            return self.juCompletionBlock2
//        }
        testBlockC { (num1, num2) -> (String,String) -> String in
            NSLog("乘机和:%@", String(num1*num2))
            return self.juCompletionBlock1
        }
    }

//block是一个参数
    func juBlockClosure(closure: (String,String) -> String) { // 函数体部分
        NSLog("函数体部分：%@",closure("参数1","参数2"))
    }

//block函数作为是一个返回值
    func juBlockClosure2(_ num : Int) -> ((String,String) -> String) {
//        1使用函数
        if num == 1 {
            func closure(string1: String , string2: String) -> String{
                NSLog("函数:参数1：%@，参数2：%@",string1,string2)
                return "9876543"
            }
            return closure
        }

//2  使用block
        return { string1,string2 in
            NSLog("闭包主体部分6:参数1：%@，参数2：%@",string1,string2)
            return "123"
            // 闭包主体部分
        }
    }

    func backward(_ s1: String, _ s2: String) -> Bool {
        return s1 > s2
    }

    func makeIncrementer(forIncrement amount: Int) -> () -> Int {
        var runningTotal = 0
        func incrementer() -> Int {
            runningTotal += amount
            return runningTotal
        }
        return incrementer
    }

    func testProperty(tag:Int)
    {
        switch (tag)
        {
        case 1:
            self.blockPropertyNoReturn("OK GOOD")
        case 2:
            if self.blockPropertyA != nil
            {
                let result = self.blockPropertyA!(7,8)
                print("result = \(result)")
            }
        case 3:
            if (self.blockPropertyB) != nil
            {
                let pc = self.blockPropertyB(1,2)
                pc("输出")
            }
        default:
            let ret = self.blockProperty(3,4)
            print(ret)
        }
    }

    //block作为函数参数
    func testBlock(blockfunc:funcBlock!)//使用!号不需要再解包
    {
        if (blockfunc) != nil
        {
            blockfunc() //无参无返回
        }
    }

    func testBlockA(blockfunc:(funcBlockA)!)
    {
        if (blockfunc) != nil
        {
            let retstr = blockfunc(5,6)
            print(retstr)
        }
    }

    func testBlockB(blockfunc:funcBlockB!)
    {
        if (blockfunc) != nil
        {
            let retfunc = blockfunc(5,6)
            retfunc("结果是")
        }
    }

    func testBlockC(blockfunc:funcBlockC!)
    {
        if (blockfunc) != nil
        {
            let retfunc = blockfunc(5,6)
            let str = retfunc("最终果结是", "第二个结果")
            NSLog(str)
        }
    }
    func test111() {

    }
    // 以下是不使用尾随闭包进行函数调用

}
